﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using Microsoft.Win32;
using System.ComponentModel;
using System.Threading;

namespace Music_Tag_Organizer
{

    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Main : Window
    {

        private GridViewColumn lastColumnSorted;
        private String m_WorkingDir = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

        private ObservableCollection<String> m_Artists = new ObservableCollection<String>();

        public ObservableCollection<String> Artists
        {
            get { return m_Artists; }
            set { m_Artists = value; }
        }

        private ObservableCollection<Track> m_TrackList = new ObservableCollection<Track>();
        public ObservableCollection<Track> TrackList
        {
            get
            {
                return m_TrackList;
            }
        }

        public Main()
        {
            InitializeComponent();
            mnuFileReload_Click(new object(), new RoutedEventArgs());


        } // end constructor

        private void mnuFile_Click(object sender, RoutedEventArgs e)
        {

        }

        private void butClose_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void lvwFiles_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0)
            {
                Track track = (Track)e.AddedItems[0];
                // Display data in controls

            }
            e.Handled = true;
        }

        private void butSwap_Click(object sender, RoutedEventArgs e)
        {
            foreach (Track track in lvwFiles.SelectedItems)
            {
                track.SwapSuggestion();
            }
        }

        private void butUseAll_Click(object sender, RoutedEventArgs e)
        {
            foreach (Track track in lvwFiles.SelectedItems)
            {
                track.UseAllSuggestions();
            }

        }

        private void butUseTitle_Click(object sender, RoutedEventArgs e)
        {
            foreach (Track track in lvwFiles.SelectedItems)
            {
                track.UseTitleSuggestion();
            }

        }

        private void butUseArtist_Click(object sender, RoutedEventArgs e)
        {
            foreach (Track track in lvwFiles.SelectedItems)
            {
                track.UseArtistSuggestion();
            }
        }

        private void butUseAlbum_Click(object sender, RoutedEventArgs e)
        {
            foreach (Track track in lvwFiles.SelectedItems)
            {
                track.UseAlbumSuggestion();
            }

        }

        private void butUseArtistAndTitle_Click(object sender, RoutedEventArgs e)
        {
            foreach (Track track in lvwFiles.SelectedItems)
            {
                track.UseArtistAndTitleSuggestion();
            }

        }

        private void butUseAll_MouseEnter(object sender, MouseEventArgs e)
        {

            //Light up suggestion text text
            txtSuggestedArtist.Foreground = Brushes.Green;
            txtSuggestedTitle.Foreground = Brushes.Green;
            txtSuggestedAlbum.Foreground = Brushes.Green;

        }

        private void butUseAll_MouseLeave(object sender, MouseEventArgs e)
        {
            txtSuggestedArtist.Foreground = Brushes.Black;
            txtSuggestedTitle.Foreground = Brushes.Black;
            txtSuggestedAlbum.Foreground = Brushes.Black;
        }

        private void butUseTitle_MouseEnter(object sender, MouseEventArgs e)
        {
            txtSuggestedTitle.Foreground = Brushes.Green;
        }

        private void butUseArtist_MouseEnter(object sender, MouseEventArgs e)
        {
            txtSuggestedArtist.Foreground = Brushes.Green;
        }

        private void butUseAlbum_MouseEnter(object sender, MouseEventArgs e)
        {
            txtSuggestedAlbum.Foreground = Brushes.Green;
        }

        private void butUseArtistAndTitle_MouseEnter(object sender, MouseEventArgs e)
        {
            txtSuggestedArtist.Foreground = Brushes.Green;
            txtSuggestedTitle.Foreground = Brushes.Green;
        }

        private void butSave_Click(object sender, RoutedEventArgs e)
        {
            MusicHandler handler = new MusicHandler();
            handler.OnWriteTracksComplete += new OnWriteTracksCompleteDelegate(handler_OnWriteTracksComplete);
            handler.OnTrackWritten += new OnTrackWriteDelegate(handler_OnTrackWritten);
            ObservableCollection<Track> tracks = new ObservableCollection<Track>();
            foreach (Track track in lvwFiles.SelectedItems)
            {
                tracks.Add(track);
            }
            handler.WriteTracksAsync(tracks);
        }

        void handler_OnTrackWritten(Track track, int count, int total)
        {
            this.Dispatcher.Invoke((Action)delegate()
            {
                this.Title = "Music Tag Organizer - Writing " + count.ToString() + " out of " + total + " tracks";
            });
        }

        void handler_OnWriteTracksComplete()
        {
            this.Dispatcher.Invoke((Action)delegate()
            {
                this.Title = "Music Tag Organizer";
            });
        }

       

        private void txtSuggestedTitle_TextChanged(object sender, TextChangedEventArgs e)
        {
            CollectionViewSource master = (CollectionViewSource)this.Resources["MasterView"];
            Track track = (Track)master.View.CurrentItem;
            if (track != null)
            {
                track.SuggestedTitle = txtSuggestedTitle.Text;
            }
        }

        private void txtSuggestedArtist_TextChanged(object sender, TextChangedEventArgs e)
        {
            CollectionViewSource master = (CollectionViewSource)this.Resources["MasterView"];
            Track track = (Track)master.View.CurrentItem;
            if (track != null)
            {
                track.SuggestedArtist = txtSuggestedArtist.Text;
            }
        }

        private void txtSuggestedAlbum_TextChanged(object sender, TextChangedEventArgs e)
        {
            foreach (Track track in lvwFiles.SelectedItems)
            {
                track.SuggestedAlbum = txtSuggestedAlbum.Text;
            }
        }

        private void mnuFileReload_Click(object sender, RoutedEventArgs e)
        {
            MusicHandler handler = new MusicHandler();
            TrackList.Clear();
            CollectionViewSource master = (CollectionViewSource)this.Resources["MasterView"];
            master.Source = TrackList;

            Artists.Clear();
            CollectionViewSource artists = (CollectionViewSource)this.Resources["ArtistView"];
            artists.Source = Artists;

            ListCollectionView view = (ListCollectionView)CollectionViewSource.GetDefaultView(lvwArtists.ItemsSource);
            view.CustomSort = new System.Collections.Comparer(System.Globalization.CultureInfo.CurrentCulture);

            handler.OnTrackRead += new OnTrackReadDelegate(handler_OnTrackRead);
            handler.OnReadTracksComplete += new OnReadTracksCompleteDelegate(handler_OnReadTracksComplete);
            handler.ReadTracksAsync(m_WorkingDir);
        }

        
        void handler_OnReadTracksComplete(ObservableCollection<Track> tracks)
        {
            this.Dispatcher.Invoke(
                (Action)delegate()
                {
                    this.Title = "Music Tag Organizer";
                });

        } // end handler


        void handler_OnTrackRead(Track track, int count, int total)
        {
            this.Dispatcher.Invoke((Action)delegate()
            {
                m_TrackList.Add(track);
                if (m_Artists.Contains(track.ContributingArtist) == false)
                {
                    m_Artists.Add(track.ContributingArtist);
                }
                this.Title = "Music Tag Organizer - Reading " + count.ToString() + " out of " + total + " tracks";
            });
        }

        private void mnuFileOpen_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFolderDlg = new OpenFileDialog();
            openFolderDlg.InitialDirectory = m_WorkingDir;

            openFolderDlg.Title = "Please choose a folder";
            openFolderDlg.CheckFileExists = false;

            openFolderDlg.FileName = "[Get Folder…]";


            if (openFolderDlg.ShowDialog() == true)
            {
                m_WorkingDir = System.IO.Path.GetDirectoryName(openFolderDlg.FileName);

            }

            mnuFileReload_Click(new object(), new RoutedEventArgs());

        }

        private void butCapitalizeWords_Click(object sender, RoutedEventArgs e)
        {
            foreach (Track track in lvwFiles.SelectedItems)
            {
                track.Capitalize();
            }
        }

        private void OnColumnHeaderClick(object sender, RoutedEventArgs e)
        {

            if (e.OriginalSource is GridViewColumnHeader)
            {
                GridViewColumn column =

                    ((GridViewColumnHeader)e.OriginalSource).Column;

                if (lastColumnSorted != null)
                {

                    lastColumnSorted.HeaderTemplate = null;

                }


                SortDescriptionCollection sorts = ((ListView)sender).Items.SortDescriptions;

                RenderSort(sorts, column, GetSortDirection(sorts, column));
            }
        }

        private void RenderSort(SortDescriptionCollection sorts,

            GridViewColumn column, ListSortDirection direction)
        {

            column.HeaderTemplate =

                (DataTemplate)this.FindResource("HeaderTemplate" + direction);

            Binding columnBinding = column.DisplayMemberBinding as Binding;

            if (columnBinding != null)
            {

                sorts.Clear();

                sorts.Add(new SortDescription(columnBinding.Path.Path, direction));

                lastColumnSorted = column;

            }

        }

        private ListSortDirection GetSortDirection(SortDescriptionCollection sorts, GridViewColumn column)
        {
            if (column == lastColumnSorted && sorts[0].Direction == ListSortDirection.Ascending)
            {
                return ListSortDirection.Descending;
            }
            return ListSortDirection.Ascending;
        }

        private void butUseSelectedArtist_Click(object sender, RoutedEventArgs e)
        {


            String artist = (String)lvwArtists.SelectedItem;

            foreach (Track track in lvwFiles.SelectedItems)
            {
                track.ContributingArtist = artist;
            }
        }

        private void mnuArtistShow_Click(object sender, RoutedEventArgs e)
        {
            String artist = (String)lvwArtists.SelectedItem;
            if (String.IsNullOrEmpty(artist) == false)
            {
                // Show only tracks that have this artist

                CollectionViewSource master = (CollectionViewSource)this.Resources["MasterView"];
                master.Source = TrackList.Where(t => t.ContributingArtist == artist);
                if (lvwFiles.Items.Count > 0)
                {
                    lvwFiles.ScrollIntoView(lvwFiles.Items[0]);
                }
            }

        }

        private void butShowAll_Click(object sender, RoutedEventArgs e)
        {
            CollectionViewSource master = (CollectionViewSource)this.Resources["MasterView"];
            master.Source = TrackList;
        }



    } // end class
} // end namespace
